package com.ruoyi.deviceevent;

import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;
import java.util.concurrent.*;

public class tcpServer {
    // 存储所有连接的客户端
    private static final Map<String, ClientHandler> clients = new ConcurrentHashMap<>();

    // 定时任务执行器
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
    // 数据库测试连接配置
    private static final String DB_URL = "jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "JiuDao@123";
    // 数据库正式连接配置
//    private static final String DB_URL = "jdbc:mysql://10.10.1.8:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
//    private static final String DB_USER = "root";
//    private static final String DB_PASSWORD = "JDMap@2012!@#";
    // 存储点表信息和设备信息
    private static final Map<Integer, PointTableInfo> pointTableMap = new ConcurrentHashMap<>();
    private static final List<DeviceInfo> deviceInfoList = new ArrayList<>();
    // 当前轮询的设备索引
    private static int deviceIndex = 0;
    // 顺序发送命令的线程池（单线程确保顺序执行）
    private static ExecutorService sendExecutor = Executors.newSingleThreadExecutor();
    // 存储待处理的请求（用于区分服务端请求和客户端主动发送的数据）
    private static final Map<String, PendingRequest> pendingRequests = new ConcurrentHashMap<>();
    // 请求超时时间（30秒）
    private static final long REQUEST_TIMEOUT = 30000;
    // 存储预构建的Modbus请求数据，以设备ID为键
    private static final Map<String, byte[]> pendingModbusRequests = new ConcurrentHashMap<>();
    // 请求队列最大大小
    private static final int MAX_PENDING_REQUESTS = 100;
    // 请求有效时间（10分钟）
    private static final long REQUEST_VALID_TIME = 10 * 60 * 1000;
    // 发送后等待时间（10秒）
    private static final long SEND_WAIT_INTERVAL = 5000;

    public static void main(String[] args) {
        // 启动时加载点表信息和设备信息
        loadPointTableFromDatabase();
        loadDeviceInfoFromDatabase();

        final int PORT = 8191;
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("Modbus设备监控服务器已启动，监听端口: " + PORT);
            // 测试启动定时任务（1分钟一次）
//            scheduler.scheduleAtFixedRate(tcpServer::pollDeviceValues, 0, 1, TimeUnit.MINUTES);
            // 正式启动定时任务为5分钟请求一次
             scheduler.scheduleAtFixedRate(tcpServer::pollDeviceValues, 0, 5, TimeUnit.MINUTES);
            // 清理过期请求任务
            scheduler.scheduleAtFixedRate(tcpServer::cleanupExpiredRequests, 0, 1, TimeUnit.MINUTES);
            // 处理待发送请求任务（每10秒检查一次）
            scheduler.scheduleAtFixedRate(tcpServer::processPendingRequests, 0, 10, TimeUnit.SECONDS);

            ExecutorService clientExecutor = Executors.newCachedThreadPool();
            while (true) {
                try {
                    Socket clientSocket = serverSocket.accept();
                    clientSocket.setKeepAlive(true);
                    clientSocket.setTcpNoDelay(true);
                    clientSocket.setSoTimeout(30000); // 30秒超时
                    System.out.println("新客户端连接: " + clientSocket.getInetAddress());
                    ClientHandler clientHandler = new ClientHandler(clientSocket);
                    clientExecutor.execute(clientHandler);
                    // 客户端连接后立即检查是否有待发送请求
                    checkAndSendPendingRequests(clientHandler);
                } catch (IOException e) {
                    System.err.println("接受客户端连接失败: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
            e.printStackTrace();
        } finally {
            scheduler.shutdown();
            sendExecutor.shutdown();
        }
    }

    // 检查并发送待处理请求
    private static void checkAndSendPendingRequests(ClientHandler clientHandler) {
        if (pendingModbusRequests.isEmpty()) {
            return;
        }
        System.out.println("新客户端连接，检查待发送请求队列，队列大小: " + pendingModbusRequests.size());
        // 使用单线程顺序处理
        sendExecutor.submit(() -> processRequestsSequentially(clientHandler, new ArrayList<>(pendingModbusRequests.entrySet())));
    }

    // 处理待发送请求
    private static void processPendingRequests() {
        if (pendingModbusRequests.isEmpty() || clients.isEmpty()) {
            return;
        }
        System.out.println("处理待发送请求，当前客户端数量: " + clients.size() +
                ", 待处理请求: " + pendingModbusRequests.size());
        // 清理过期请求
        cleanupExpiredPendingRequests();
        // 查找可用客户端
        if (!clients.isEmpty()) {
            List<ClientHandler> clientList = new ArrayList<>(clients.values());
            ClientHandler availableClient = findAvailableClient(clientList);
            if (availableClient != null) {
                // 提交顺序发送任务
                sendExecutor.submit(() -> processRequestsSequentially(availableClient, new ArrayList<>(pendingModbusRequests.entrySet())));
            }
        }
    }

    // 核心修改：顺序处理请求，每个发送后等待10秒
    private static void processRequestsSequentially(ClientHandler client, List<Map.Entry<String, byte[]>> requests) {
        if (client == null || !client.isConnectionHealthy() || requests.isEmpty()) {
            System.out.println("顺序发送任务终止：客户端不可用或无请求");
            return;
        }

        System.out.println("开始顺序发送" + requests.size() + "个请求，间隔10秒");
        int sentCount = 0;

        for (Map.Entry<String, byte[]> entry : requests) {
            String deviceId = entry.getKey();
            byte[] modbusRequest = entry.getValue();

            // 检查请求是否仍在队列中（可能已被处理）
            if (!pendingModbusRequests.containsKey(deviceId)) {
                System.out.println("请求已处理，跳过设备" + deviceId);
                continue;
            }

            // 检查客户端连接状态
            if (!client.isConnectionHealthy()) {
                System.out.println("客户端连接异常，终止顺序发送");
                break;
            }

            // 发送请求
            System.out.println("顺序发送请求：设备" + deviceId + "（当前第" + (sentCount + 1) + "个）");
            boolean success = client.sendPrebuiltModbusRequest(modbusRequest, deviceId);

            if (success) {
                pendingModbusRequests.remove(deviceId);
                sentCount++;
                System.out.println("设备" + deviceId + "请求发送成功");
            } else {
                System.out.println("设备" + deviceId + "请求发送失败，保留在队列");
            }

            // 不是最后一个请求则等待10秒
            if (sentCount < requests.size()) {
                try {
                    System.out.println("等待" + (SEND_WAIT_INTERVAL / 1000) + "秒后发送下一个请求...");
                    Thread.sleep(SEND_WAIT_INTERVAL);
                } catch (InterruptedException e) {
                    System.err.println("等待被中断：" + e.getMessage());
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        System.out.println("顺序发送任务完成，成功发送" + sentCount + "个请求，剩余队列大小: " + pendingModbusRequests.size());
    }

    // 查找可用的客户端
    private static ClientHandler findAvailableClient(List<ClientHandler> clientList) {
        for (ClientHandler client : clientList) {
            if (client.isConnectionHealthy() && clients.containsKey(client.clientId)) {
                return client;
            }
        }
        return null;
    }

    // 清理过期待发送请求
    private static void cleanupExpiredPendingRequests() {
        while (pendingModbusRequests.size() > MAX_PENDING_REQUESTS) {
            Iterator<String> iterator = pendingModbusRequests.keySet().iterator();
            if (iterator.hasNext()) {
                String oldestDeviceId = iterator.next();
                pendingModbusRequests.remove(oldestDeviceId);
                System.out.println("待发送请求队列超过最大限制，移除请求: 设备" + oldestDeviceId);
            }
        }
    }

    // 清理过期请求
    private static void cleanupExpiredRequests() {
        long currentTime = System.currentTimeMillis();
        Iterator<Map.Entry<String, PendingRequest>> iterator = pendingRequests.entrySet().iterator();
        int cleanedCount = 0;

        while (iterator.hasNext()) {
            Map.Entry<String, PendingRequest> entry = iterator.next();
            if (currentTime - entry.getValue().getTimestamp() > REQUEST_TIMEOUT) {
                iterator.remove();
                cleanedCount++;
            }
        }

        if (cleanedCount > 0) {
            System.out.println("清理了 " + cleanedCount + " 个过期请求");
        }
    }

    // 从数据库加载设备信息
    private static void loadDeviceInfoFromDatabase() {
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            String sql = "SELECT id, device_address FROM modbus_device WHERE del_flag = 0";
            try (PreparedStatement pstmt = conn.prepareStatement(sql);
                 ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    String deviceId = rs.getString("id");
                    int deviceAddress = rs.getInt("device_address");
                    DeviceInfo deviceInfo = new DeviceInfo(deviceId, deviceAddress);
                    deviceInfoList.add(deviceInfo);
                    System.out.println("加载设备信息: 设备ID=" + deviceId + ", 设备地址=" + deviceAddress);
                }
                System.out.println("设备信息加载完成，共加载 " + deviceInfoList.size() + " 个设备");
            }
        } catch (SQLException e) {
            System.err.println("加载设备信息失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 从数据库加载点表配置
    private static void loadPointTableFromDatabase() {
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            String sql = "SELECT id, code, name, detail, remark, attribute, transfor FROM modbus_point WHERE del_flag = 0";
            try (PreparedStatement pstmt = conn.prepareStatement(sql);
                 ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    int id = rs.getInt("id");
                    int code = rs.getInt("code");
                    String name = rs.getString("name");
                    String detail = rs.getString("detail");
                    String remark = rs.getString("remark");
                    String attribute = rs.getString("attribute");
                    String transfor = rs.getString("transfor");
                    int decimalPlaces = parseDecimalPlacesFromTransfor(transfor);
                    double scale = Math.pow(10, -decimalPlaces);
                    int modbusAddress = code - 40001;
                    PointTableInfo pointInfo = new PointTableInfo(
                            id, code, name, detail, remark, attribute, transfor,
                            scale, getUnitFromParameterName(name)
                    );
                    pointTableMap.put(modbusAddress, pointInfo);
                }
                System.out.println("点表加载完成，共加载 " + pointTableMap.size() + " 个点");
            }
        } catch (SQLException e) {
            System.err.println("加载点表配置失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 从transfor字段解析小数位数
    private static int parseDecimalPlacesFromTransfor(String transfor) {
        if (transfor == null || transfor.trim().isEmpty()) return 0;
        if (transfor.contains("2位小数") || transfor.contains("2 位小数")) return 2;
        if (transfor.contains("1位小数") || transfor.contains("1 位小数")) return 1;
        if (transfor.contains("0位小数") || transfor.contains("0 位小数")) return 0;
        if (transfor.contains("3位小数") || transfor.contains("3 位小数")) return 3;
        try {
            java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d+)");
            java.util.regex.Matcher matcher = pattern.matcher(transfor);
            if (matcher.find()) {
                return Integer.parseInt(matcher.group(1));
            }
        } catch (Exception e) {
            System.err.println("解析小数位数失败: " + transfor);
        }
        return 0;
    }

    // 根据参数名称推断单位
    private static String getUnitFromParameterName(String parameterName) {
        if (parameterName == null) return "";
        if (parameterName.contains("温度")) return "℃";
        if (parameterName.contains("压力")) return "kPa";
        if (parameterName.contains("流量")) return "t/h";
        if (parameterName.contains("累计") || parameterName.contains("累")) return "t";
        if (parameterName.contains("时间")) return "小时";
        if (parameterName.contains("频率")) return "Hz";
        if (parameterName.contains("热量") || parameterName.contains("热")) return "t";
        if (parameterName.contains("焓值")) return "kJ/kg";
        if (parameterName.contains("密度")) return "kg/m³";
        if (parameterName.contains("电流")) return "mA";
        if (parameterName.contains("差压")) return "MPa";
        return "";
    }

    // 定时获取设备值 - 使用预构建的Modbus请求
    private static void pollDeviceValues() {
        System.out.println("=== 开始执行定时设备值轮询 ===");

        if (deviceInfoList.isEmpty()) {
            System.out.println("没有设备信息，跳过轮询");
            return;
        }

        if (clients.isEmpty()) {
            System.out.println("当前没有客户端连接，将所有设备请求加入待发送队列");
            for (DeviceInfo device : deviceInfoList) {
                String deviceId = device.getDeviceId();
                byte[] modbusRequest = buildModbusRequestForDevice(device);
                if (modbusRequest != null) {
                    pendingModbusRequests.put(deviceId, modbusRequest);
                    System.out.println("设备" + deviceId + "请求加入队列（地址：" +
                            Integer.toHexString(device.getDeviceAddress()).toUpperCase() + "）");
                }
            }
            return;
        }

        System.out.println("将" + deviceInfoList.size() + "个设备命令加入发送队列");
        for (DeviceInfo device : deviceInfoList) {
            byte[] modbusRequest = buildModbusRequestForDevice(device);
            if (modbusRequest != null) {
                pendingModbusRequests.put(device.getDeviceId(), modbusRequest);
            }
        }
    }

    // 为设备构建Modbus请求
    private static byte[] buildModbusRequestForDevice(DeviceInfo device) {
        try {
            int startAddr = 0; // 起始地址固定为0
            int registerCount = 15; // 寄存器数量固定为15
            byte slaveAddress = device.getDeviceAddressHex(); // 设备地址转为16进制字节
            byte functionCode = (byte) 0x03; // 读保持寄存器功能码

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            baos.write(slaveAddress);       // 从站地址（1字节）
            baos.write(functionCode);       // 功能码（1字节）
            baos.write((startAddr >> 8) & 0xFF); // 起始地址高8位
            baos.write(startAddr & 0xFF);        // 起始地址低8位
            baos.write((registerCount >> 8) & 0xFF); // 寄存器数量高8位
            baos.write(registerCount & 0xFF);        // 寄存器数量低8位

            byte[] data = baos.toByteArray();
            int crc = calculateCRC(data);    // 计算CRC校验
            baos.write(crc & 0xFF);          // CRC低8位
            baos.write((crc >> 8) & 0xFF);   // CRC高8位

            return baos.toByteArray();
        } catch (Exception e) {
            System.err.println("构建Modbus请求失败: " + e.getMessage());
            return null;
        }
    }

    // Modbus CRC16计算
    private static int calculateCRC(byte[] data) {
        int crc = 0xFFFF;
        for (byte b : data) {
            crc ^= (b & 0xFF);
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) != 0) {
                    crc = (crc >> 1) ^ 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return crc;
    }

    // 保存数据到数据库
    private static void saveToDatabase(String deviceId, int deviceAddress, String clientInfo, Map<String, Object> data) {
        if (!isDeviceExistsInDatabase(deviceId)) {
            System.out.println("设备 " + deviceId + " 不在数据库中，跳过保存");
            return;
        }

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            // 新增combined_value列存储保留两位小数的计算结果
            String sql = "INSERT INTO modbus_data (" +
                    "device_id, device_address, register_address, register_value, " +
                    "parameter_name, physical_value, unit, create_time, point_id, " +
                    "combined_value) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                Timestamp timestamp = new Timestamp(System.currentTimeMillis());
                List<Integer> registerValues = (List<Integer>) data.get("register_values");
//                if (registerValues == null) {
//                    System.out.println("没有寄存器数据");
//                    return;
//                }

                int savedCount = 0;
                for (int i = 0; i < registerValues.size(); i++) {
                    int registerValue = registerValues.get(i);
                    int modbusAddress = i;
                    PointTableInfo pointInfo = getPointTableInfo(modbusAddress);

                    if (pointInfo == null || pointInfo.getId() == 0) {
                        System.out.println("跳过无效的点表配置: Modbus地址=" + modbusAddress);
                        continue;
                    }

                    double physicalValue = calculatePhysicalValue(registerValue, pointInfo);
                    Double combinedValue = null;

                    if (pointInfo.getId() == 10) {  // 仅对point_id=10计算
                        if (i - 1 >= 0) {
                            int sh001 = registerValues.get(i - 1);
                            int sl001 = registerValue;
                            // 1. 计算原始组合值
                            double rawValue = (sh001 * 65536.0 + sl001) * 0.01;
                            // 2. 保留两位小数（四舍五入）
                            combinedValue = Math.round(rawValue * 100) / 100.0;  // 核心处理
                            System.out.println("point_id=10 组合值（保留两位小数）: " + combinedValue);
                        } else {
                            System.out.println("point_id=10 高位寄存器索引无效，无法计算");
                        }
                    }

                    // 设置参数（第10个为保留两位小数的组合值）
                    pstmt.setString(1, deviceId);
                    pstmt.setString(2, clientInfo);
                    pstmt.setInt(3, pointInfo.getRegisterAddress());
                    pstmt.setInt(4, registerValue);
                    pstmt.setString(5, pointInfo.getParameterName());
                    pstmt.setDouble(6, physicalValue);
                    pstmt.setString(7, getUnitFromParameterName(pointInfo.getDetail()));
                    pstmt.setTimestamp(8, timestamp);
                    pstmt.setInt(9, pointInfo.getId());
                    pstmt.setObject(10, combinedValue);  // 存储两位小数的结果

                    pstmt.addBatch();
                    savedCount++;
                }

                if (savedCount > 0) {
                    pstmt.executeBatch();
                    System.out.println("设备 " + deviceId + " 数据已保存到数据库，共保存 " + savedCount + " 条记录");
                } else {
                    System.out.println("设备 " + deviceId + " 没有有效数据需要保存");
                }
            }
        } catch (SQLException e) {
            System.err.println("保存数据到数据库失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 检查设备是否在数据库中存在
    private static boolean isDeviceExistsInDatabase(String deviceId) {
        for (DeviceInfo device : deviceInfoList) {
            if (device.getDeviceId().equals(deviceId)) {
                return true;
            }
        }
        return false;
    }

    // 根据Modbus地址获取点表信息
    private static PointTableInfo getPointTableInfo(int modbusAddress) {
        PointTableInfo pointInfo = pointTableMap.get(modbusAddress);
        if (pointInfo != null) {
            return pointInfo;
        } else {
            System.out.println("警告: 未找到Modbus地址 " + modbusAddress + " 的点表配置");
            return new PointTableInfo(0, modbusAddress + 40001,
                    "未知参数" + modbusAddress, "未配置", "默认配置", "R", "0位小数",
                    1.0, "");
        }
    }

    // 计算物理值
    private static double calculatePhysicalValue(int registerValue, PointTableInfo info) {
        return registerValue * info.getScale();
    }

    // 设备信息类
    private static class DeviceInfo {
        private String deviceId;
        private int deviceAddress;

        public DeviceInfo(String deviceId, int deviceAddress) {
            this.deviceId = deviceId;
            this.deviceAddress = deviceAddress;
        }

        public String getDeviceId() { return deviceId; }
        public int getDeviceAddress() { return deviceAddress; }
        public byte getDeviceAddressHex() { return (byte) (deviceAddress & 0xFF); }
    }

    // 待处理请求类
    private static class PendingRequest {
        private String requestId;
        private String deviceId;
        private long timestamp;

        public PendingRequest(String requestId, String deviceId) {
            this.requestId = requestId;
            this.deviceId = deviceId;
            this.timestamp = System.currentTimeMillis();
        }

        public String getRequestId() { return requestId; }
        public String getDeviceId() { return deviceId; }
        public long getTimestamp() { return timestamp; }
    }

    // 客户端处理类
    private static class ClientHandler implements Runnable {
        protected Socket socket;
        protected OutputStream out;
        protected InputStream in;
        protected String clientId;

        public ClientHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                in = socket.getInputStream();
                out = socket.getOutputStream();
                clientId = socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
                System.out.println("客户端连接: " + clientId);

                clients.put(clientId, this);

                socket.setSoTimeout(30000); // 30秒超时

                handleDevice();
            } catch (IOException e) {
                System.err.println("客户端连接异常: " + e.getMessage());
            } finally {
                disconnect();
            }
        }

        // 检查连接健康状态
        public boolean isConnectionHealthy() {
            if (socket == null || socket.isClosed() || !socket.isConnected()) {
                return false;
            }
            if (in == null || out == null) {
                return false;
            }
            try {
                if (socket.isInputShutdown() || socket.isOutputShutdown()) {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        // 发送Modbus请求到设备
        public boolean sendModbusRequest() {
            if (!isConnectionHealthy()) {
                System.out.println("客户端 " + clientId + " 连接不可用，不发送请求");
                return false;
            }

            if (deviceInfoList.isEmpty()) {
                System.out.println("没有设备信息，不发送请求");
                return false;
            }

            try {
                DeviceInfo currentDevice = deviceInfoList.get(deviceIndex);
                return sendSpecificModbusRequest(currentDevice);
            } catch (Exception e) {
                System.err.println("发送Modbus请求异常: " + e.getMessage());
                return false;
            }
        }

        // 发送特定设备的Modbus请求
        public boolean sendSpecificModbusRequest(DeviceInfo device) {
            if (!isConnectionHealthy()) {
                System.out.println("发送前连接检查失败: " + clientId);
                return false;
            }

            try {
                System.out.println("向客户端 " + clientId + " 请求特定设备: " + device.getDeviceId());

                byte[] modbusRequest = buildModbusRequestForDevice(device);
                if (modbusRequest == null) {
                    System.out.println("构建Modbus请求失败");
                    return false;
                }

                String requestId = generateRequestId(device.getDeviceId());
                PendingRequest pendingRequest = new PendingRequest(requestId, device.getDeviceId());
                pendingRequests.put(requestId, pendingRequest);

                System.out.println("准备发送Modbus请求到客户端 " + clientId + ", 请求ID: " + requestId);

                boolean sendSuccess = false;
                long startTime = System.currentTimeMillis();

                try {
                    out.write(modbusRequest);
                    out.flush();
                    long endTime = System.currentTimeMillis();

                    if (isConnectionHealthy() && (endTime - startTime) < 5000) {
                        sendSuccess = true;
                        System.out.println("请求发送成功，耗时: " + (endTime - startTime) + "ms");

                        if (device == deviceInfoList.get(deviceIndex)) {
                            deviceIndex = (deviceIndex + 1) % deviceInfoList.size();
                        }
                    } else {
                        System.out.println("请求发送可能失败，连接状态异常或超时");
                    }
                } catch (IOException e) {
                    System.err.println("发送数据时发生IO异常: " + e.getMessage());
                    sendSuccess = false;
                }

                if (!sendSuccess) {
                    pendingRequests.remove(requestId);
                    System.out.println("请求发送失败，已从待处理列表中移除: " + requestId);
                }

                return sendSuccess;

            } catch (Exception e) {
                System.err.println("发送特定设备Modbus请求异常: " + e.getMessage());
                return false;
            }
        }

        // 发送预构建的Modbus请求（核心发送方法）
        public boolean sendPrebuiltModbusRequest(byte[] modbusRequest, String deviceId) {
            if (!isConnectionHealthy()) {
                System.out.println("发送前连接检查失败: " + clientId);
                return false;
            }

            try {
                System.out.println("向客户端 " + clientId + " 发送预构建的Modbus请求: 设备" + deviceId);
                System.out.println("Modbus请求数据: " + bytesToHex(modbusRequest));

                // 生成请求ID并记录
                String requestId = generateRequestId(deviceId);
                PendingRequest pendingRequest = new PendingRequest(requestId, deviceId);
                pendingRequests.put(requestId, pendingRequest);

                boolean sendSuccess = false;
                long startTime = System.currentTimeMillis();

                try {
                    out.write(modbusRequest);
                    out.flush();
                    long endTime = System.currentTimeMillis();

                    // 验证发送是否成功
                    if (isConnectionHealthy() && (endTime - startTime) < 5000) {
                        sendSuccess = true;
                        System.out.println("预构建请求发送成功，耗时: " + (endTime - startTime) + "ms");
                    } else {
                        System.out.println("预构建请求发送可能失败，连接状态异常或超时");
                    }
                } catch (IOException e) {
                    System.err.println("发送预构建数据时发生IO异常: " + e.getMessage());
                    sendSuccess = false;
                }

                if (!sendSuccess) {
                    pendingRequests.remove(requestId);
                    System.out.println("预构建请求发送失败: 设备" + deviceId);
                }

                return sendSuccess;

            } catch (Exception e) {
                System.err.println("发送预构建Modbus请求异常: " + e.getMessage());
                return false;
            }
        }

        // 生成请求ID
        private String generateRequestId(String deviceId) {
            return deviceId + "_" + System.currentTimeMillis() + "_" + Thread.currentThread().getId();
        }

        // 构建Modbus RTU请求帧
        private byte[] buildModbusRequestForDevice(DeviceInfo device) {
            try {
                int startAddr = 0;
                int registerCount = pointTableMap.size();
                byte slaveAddress = device.getDeviceAddressHex();
                byte functionCode = (byte) 0x03;

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                baos.write(slaveAddress);
                baos.write(functionCode);
                baos.write((startAddr >> 8) & 0xFF);
                baos.write(startAddr & 0xFF);
                baos.write((registerCount >> 8) & 0xFF);
                baos.write(registerCount & 0xFF);

                byte[] data = baos.toByteArray();
                int crc = calculateCRC(data);
                baos.write(crc & 0xFF);
                baos.write((crc >> 8) & 0xFF);

                return baos.toByteArray();
            } catch (Exception e) {
                System.err.println("构建Modbus请求失败: " + e.getMessage());
                return null;
            }
        }

        // Modbus CRC16计算
        private int calculateCRC(byte[] data) {
            int crc = 0xFFFF;
            for (byte b : data) {
                crc ^= (b & 0xFF);
                for (int i = 0; i < 8; i++) {
                    if ((crc & 0x0001) != 0) {
                        crc = (crc >> 1) ^ 0xA001;
                    } else {
                        crc = crc >> 1;
                    }
                }
            }
            return crc;
        }

        // 客户端断开连接
        protected synchronized void disconnect() {
            if (socket == null || socket.isClosed()) {
                clients.remove(clientId);
                return;
            }

            try {
                if (out != null) out.close();
                if (in != null) in.close();
                if (socket != null) socket.close();
                System.out.println("客户端 " + clientId + " 已断开连接并从列表中移除");
            } catch (IOException e) {
                System.err.println("关闭客户端连接时出错: " + e.getMessage());
            } finally {
                clients.remove(clientId);
                out = null;
                in = null;
                socket = null;
            }
        }

        // 处理设备客户端（接收响应）
        protected void handleDevice() throws IOException {
                System.out.println("开始处理设备数据: " + clientId);
                byte[] buffer = new byte[1024];
                int bytesRead;

                try {
                    while ((bytesRead = in.read(buffer)) != -1) {
                        byte[] responseData = Arrays.copyOf(buffer, bytesRead);

                        System.out.println("收到来自 " + clientId + " 的消息，长度: " + bytesRead + " 字节");
                        System.out.println("原始数据: " + bytesToHex(responseData));

                        // 检查是否是服务端请求的响应
                        if (isResponseToServerRequest(responseData)) {
                            // 解析Modbus响应（已包含CRC校验）
                            Map<String, Object> parsedData = parseModbusResponse(responseData);
                            if (parsedData != null) {
                                System.out.println("Modbus响应解析成功");
                            } else {
                                System.out.println("Modbus响应解析失败");
                            }
                        } else {
                            // 处理客户端主动发送的数据
                            System.out.println("处理客户端主动发送的数据");
                            // 1. 校验CRC（强制校验最后两位）
                            if (!verifyCRC(responseData)) {
                                System.err.println("客户端主动数据CRC校验失败（最后两位不符），不处理");
                                continue;
                            }
                            // 2. 解析主动发送的数据（复用现有解析逻辑）
                            Map<String, Object> parsedData = parseModbusResponse(responseData);
                            if (parsedData != null) {
                                System.out.println("客户端主动数据解析成功，已保存匹配到的设备数据");
                            } else {
                                System.out.println("客户端主动数据未匹配到设备，不保存");
                            }
                        }
                    }
                } catch (SocketTimeoutException e) {
                    System.out.println("读取数据超时，客户端可能无响应: " + clientId);
                } catch (SocketException e) {
                    if (e.getMessage().contains("Connection reset") || e.getMessage().contains("连接被重置")) {
                        System.out.println("连接被重置: " + clientId);
                    } else {
                        System.err.println("Socket异常: " + e.getMessage());
                    }
                    throw e;
                } catch (IOException e) {
                    System.err.println("读取数据异常: " + e.getMessage());
                    throw e;
                }
            }

        // 检查是否是服务端请求的响应
        private boolean isResponseToServerRequest(byte[] response) {
            if (response.length < 5) {
                return false;
            }

            if (!verifyCRC(response)) {
                return false;
            }

            int receivedDeviceAddress = response[0] & 0xFF;

            return hasPendingRequestForDevice(receivedDeviceAddress);
        }

        // 检查是否有对应设备的待处理请求
        private boolean hasPendingRequestForDevice(int deviceAddress) {
            DeviceInfo device = findDeviceByAddress(deviceAddress);
            if (device == null) return false;

            long currentTime = System.currentTimeMillis();
            for (PendingRequest request : pendingRequests.values()) {
                if (request.getDeviceId().equals(device.getDeviceId()) &&
                        currentTime - request.getTimestamp() < REQUEST_TIMEOUT) {
                    pendingRequests.remove(request.getRequestId());
                    return true;
                }
            }
            return false;
        }

        // 解析Modbus响应
        private Map<String, Object> parseModbusResponse(byte[] response) {
            if (response.length < 5) {
                System.err.println("响应长度不足（至少5字节）");
                return null;
            }

            if (!verifyCRC(response)) {
                System.err.println("CRC校验失败，响应无效");
                return null;
            }

            int receivedDeviceAddress = response[0] & 0xFF;
            System.out.println("收到从站地址为" + Integer.toHexString(receivedDeviceAddress).toUpperCase() +
                    "的响应，长度：" + response.length + "字节");

            DeviceInfo device = findDeviceByAddress(receivedDeviceAddress);
            if (device == null) {
                System.err.println("未找到从站地址为" + Integer.toHexString(receivedDeviceAddress).toUpperCase() + "的设备");
                return null;
            }

            System.out.println("匹配到设备：" + device.getDeviceId() + "（地址：" +
                    Integer.toHexString(receivedDeviceAddress).toUpperCase() + "）");

            byte functionCode = response[1];
            if ((functionCode & 0x80) != 0) {
                int errorCode = response[2] & 0xFF;
                System.err.println("设备" + device.getDeviceId() + "返回错误，错误码：" + errorCode);
                return null;
            }

            byte byteCount = response[2];
//            if (response.length != byteCount + 5) {
//                System.err.println("数据长度不匹配（期望：" + (byteCount + 5) + "，实际：" + response.length + "）");
//                return null;
//            }

            Map<String, Object> result = new HashMap<>();
            result.put("slave_address", receivedDeviceAddress);
            result.put("function_code", functionCode & 0xFF);
            result.put("byte_count", byteCount & 0xFF);

            List<Integer> registerValues = new ArrayList<>();
            int registerIndex = 0;
            for (int i = 3; i < 3 + byteCount; i += 2) {
                if (i + 1 > 3 + byteCount - 1) break;
                int highByte = response[i] & 0xFF;
                int lowByte = response[i + 1] & 0xFF;
                int value = (highByte << 8) | lowByte;
                registerValues.add(value);
                result.put("register_" + registerIndex, value);

                PointTableInfo pointInfo = getPointTableInfo(registerIndex);
                if (pointInfo != null) {
                    double physicalValue = calculatePhysicalValue(value, pointInfo);
                    result.put("physical_value_" + registerIndex, physicalValue);
                }
                registerIndex++;
            }
            result.put("register_values", registerValues);
            System.out.println("设备" + device.getDeviceId() + "解析成功，共" + registerValues.size() + "个寄存器值");

            // 存储到数据库
            saveToDatabase(device.getDeviceId(), device.getDeviceAddress(), clientId, result);
            return result;
        }

        // 根据设备地址查找设备信息
        private DeviceInfo findDeviceByAddress(int deviceAddress) {
            for (DeviceInfo device : deviceInfoList) {
                if (device.getDeviceAddress() == deviceAddress) {
                    return device;
                }
            }
            return null;
        }

        // 验证CRC
        private boolean verifyCRC(byte[] data) {
            if (data.length < 2) return false;
            int length = data.length - 2;
            int receivedCRC = ((data[length] & 0xFF) | ((data[length + 1] & 0xFF) << 8));
            int calculatedCRC = calculateCRC(Arrays.copyOf(data, length));
            return receivedCRC == calculatedCRC;
        }

        // 字节数组转十六进制字符串
        private String bytesToHex(byte[] bytes) {
            StringBuilder hex = new StringBuilder();
            for (byte b : bytes) {
                hex.append(String.format("%02X ", b));
            }
            return hex.toString().trim();
        }
    }

    // 点表信息类
    private static class PointTableInfo {
        private int id;
        private int registerAddress;
        private String parameterName;
        private String detail;
        private String remark;
        private String attribute;
        private String transfor;
        private double scale;
        private String unit;

        public PointTableInfo(int id, int registerAddress, String parameterName,
                              String detail, String remark, String attribute, String transfor,
                              double scale, String unit) {
            this.id = id;
            this.registerAddress = registerAddress;
            this.parameterName = parameterName;
            this.detail = detail;
            this.remark = remark;
            this.attribute = attribute;
            this.transfor = transfor;
            this.scale = scale;
            this.unit = unit;
        }

        public int getId() { return id; }
        public int getRegisterAddress() { return registerAddress; }
        public String getParameterName() { return parameterName; }
        public String getDetail() { return detail; }
        public String getRemark() { return remark; }
        public String getAttribute() { return attribute; }
        public String getTransfor() { return transfor; }
        public double getScale() { return scale; }
        public String getUnit() { return unit; }
    }
}